# 魔法方法和属性, 在python中，魔法方法是以双下划线开头和结尾的方法

# __doc__() 方法: 类的描述信息

class Person(object):
    """Person类的描述信息"""
    pass

print(Person.__doc__) # Person类的描述信息,只能用三引号的方式书写

# __module__: 获取类所在的模块名
print(Person.__module__) # __main__

# __class__: 获取类的类型
print(Person.__class__) # <class 'type'>

# __name__: 获取类的名称
print(Person.__name__) # Person

# __str__: 如果类中定义了此方法,那么在打印对象时, 默认输出该方法的返回值, 也就是打印方法中return的数据
# __str__: 必须返回一个字符串, 否则会报错
p1 = Person()
print(p1.__str__())


# __del__: 析构函数 当对象被销毁时,自动调用此方法


# callable: 使一个实例对象成为一个可调用对象, 就像函数那样可以调用
# 可调用对象: 函数和内置函数和类都是可调用对象, 凡是可以一对()应用到某个对象身上都可以称之为可调用对象
def foo():
    print("foo() called")

print(callable(foo)) # True, foo是一个可调用对象
name = "John"
print(callable(name)) # False, name不是一个可调用对象

print(callable(Person)) # True, Person是一个可调用对象

# 调用一个可调用的实例对象, 其实就是在调用它的 __call__方法

class A(object):
    def __call__(self, *args, **kwargs):
        print("A.__call__() called with args:", args, "and kwargs:", kwargs)
a = A()
a() # 调用一个可调用的实例对象, 其实就是在调用它的 __call__方法
print(callable(a)) # True, a是一个可调用对象

